/*
 * @Author: LiuYan
 * @Date: 2022-12-16 11:53:29
 * @LastEditors: LiuYan
 * @LastEditTime: 2023-01-03 17:26:59
 * @Description:
 */
export default class Tree {
  constructor({
    data, // 数据
    el, // 根元素
    isOpen = true, // 默认是否打开
    click, // 点击回调
    checkedClick, // 点击复选框回调
    isCheckBox = false, //是否开启checkbox
    checkedIds = [], // 默认选中
    all = true,
  }) {
    this._el = document.querySelector(el);
    this._data = data;
    this._isOpen = isOpen;
    this._click = click;
    this._checkedClick = checkedClick;
    this._isCheckBox = isCheckBox;
    this._checkedIds = checkedIds;
    this._all = all;
    this.checkedList = [];
    this.count = 0;
    this.initRecurve(this._data, this._el, false, null, null);
  }
  // 递归遍历树结构
  initRecurve(data, el, isPadding, oldItem, oldDiv) {
    data.forEach((item, index) => {
      item.isOpen = this._isOpen;
      item.isCheckBox = this._checkedIds.includes(item.id) ? true : false;
      const div = document.createElement("div");
      const p = document.createElement("p");
      p.innerHTML =
        `<span></span><span></span>${item.name}` +
        (item.innerHTML ? item.innerHTML : "");
      div.className = "tree-item";
      p.addEventListener("mouseover", (e) => {
        p.style.backgroundColor = "#f5f7fa";
      });
      p.addEventListener("mouseout", (e) => {
        p.style.backgroundColor = "transparent";
      });
      div.addEventListener("click", (e) => {
        e.preventDefault();
        e.stopPropagation();
        item.isOpen = !item.isOpen;
        if (this._click) this._click(item);
        const span = div.childNodes[0].childNodes[0];
        if (item.isOpen) {
          span.style.transform = "rotate(90deg)";
        } else {
          span.style.transform = "rotate(0deg)";
        }
        if (div.childNodes && div.childNodes.length > 1) {
          div.childNodes.forEach((_item, _index) => {
            if (_index != 0)
              _item.style.display = item.isOpen ? "block" : "none";
          });
        }
      });
      div.appendChild(p);
      el.appendChild(div);
      let span_1 = div.childNodes[0].childNodes[0];
      let span_2 = div.childNodes[0].childNodes[1];
      div.setAttribute("index", item.id);
      span_2.setAttribute("index", item.id);
      // 判断是否为复选框
      if (this._isCheckBox) {
        span_1.className = "trigonometry";
        if (this._all) {
          span_2.className = item.isCheckBox ? "checkbox_active" : "checkbox";
        }
        span_2.addEventListener("click", (e) => {
          e.preventDefault();
          e.stopPropagation();
          item.isCheckBox = !item.isCheckBox;
          if (oldItem) {
            let count = 0;
            if (oldItem.child && oldItem.child.length) {
              oldItem.child.forEach((e) => {
                if (e.isCheckBox) count++;
              });
              if (count >= 1) {
                this.recurveParent(div, true);
              } else {
                this.recurveParent(div, false);
              }
            }
          }
          if (this._checkedClick) this._checkedClick(item);
          if (this._all) {
            this.recurveDom([div], item.isCheckBox);
            this.recurveData([item], item.isCheckBox);
          } else {
            if (!item.child)
              span_2.className = item.isCheckBox
                ? "checkbox_active"
                : "checkbox";
          }
        });
      } else {
        span_1.className = "trigonometry";
      }
      if (item.isOpen) {
        span_1.style.transform = "rotate(90deg)";
      } else {
        span_1.style.transform = "rotate(0deg)";
      }
      if (isPadding) {
        // this.count++;
        // console.log(this.count, item.name);
        div.style.display = item.isOpen ? "block" : "none";
      }
      p.style.paddingLeft = item.level * 12 + "px";
      if (item.child && item.child.length) {
        this.initRecurve(item.child, div, true, item, span_2);
      } else {
        if (this._isCheckBox) {
          span_1.style.opacity = 0;
          span_2.className = this._checkedIds.includes(item.id)
            ? "checkbox_active"
            : "checkbox";
        } else {
          span_1.style.opacity = 0;
        }
        // p.style.paddingLeft = (this.count + 1) * 12 + "px";
        // console.log(this.count, item.name);
        // this.count = 0;
      }
    });
  }
  //获取选中的元素
  getCheckBox() {
    this.checkedList = [];
    this.recurve([this._el]);
    return {
      checkedList: this.checkedList,
      data: this._data,
    };
  }
  recurve(data) {
    data.forEach((item) => {
      if (
        item.getAttribute &&
        item.tagName == "SPAN" &&
        item.getAttribute("class") == "checkbox_active"
      ) {
        this.checkedList.push(item.getAttribute("index"));
      }
      if (item.childNodes && item.childNodes.length) {
        this.recurve(item.childNodes);
      }
    });
  }
  recurveDom(el, isCheckBox) {
    el.forEach((item) => {
      if (
        item.getAttribute &&
        (item.getAttribute("class") == "checkbox" ||
          item.getAttribute("class") == "checkbox_active")
      ) {
        isCheckBox
          ? (item.className = "checkbox_active")
          : (item.className = "checkbox");
      }
      if (item.childNodes && item.childNodes.length > 0) {
        this.recurveDom(item.childNodes, isCheckBox);
      }
    });
  }
  recurveData(data, isCheckBox) {
    data.forEach((item) => {
      // console.log(item);
      item.isCheckBox = isCheckBox;
      if (item.child && item.child.length > 0) {
        this.recurveData(item.child, isCheckBox);
      }
    });
  }
  recurveParent(next, flag) {
    if (next.childNodes[0].childNodes[1]) {
      let className = "";
      flag ? (className = "checkbox_active") : (className = "checkbox");
      next.childNodes[0].childNodes[1].className = className;
    }
    this.recurveDom2([next], next);
    if (next.getAttribute("class") != "tree") {
      this.recurveParent(next.parentElement, flag);
    }
  }
  recurveDom2(el, el_2) {
    this.count = 0;
    el.forEach((item) => {
      if (
        item.getAttribute &&
        el_2.getAttribute &&
        item.getAttribute("index") &&
        el_2.getAttribute("index") &&
        item.getAttribute("index") == el_2.getAttribute("index")
      ) {
        item.childNodes.forEach((_item) => {
          if (_item.getAttribute && _item.getAttribute("index")) {
            if (
              _item.childNodes[0].childNodes[1].className == "checkbox_active"
            )
              this.count++;
          }
        });
        if (this.count != 0) {
          item.childNodes[0].childNodes[1].className = "checkbox_active";
        }
      }
      if (item.getAttribute && item.getAttribute("index")) {
        // console.log("item_02", item);
      }
      if (item.childNodes && item.childNodes.length > 0) {
        this.recurveDom2(item.childNodes, el_2);
      }
    });
  }
}
